
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
const jsdom = require("jsdom");
const {JSDOM} = jsdom;
const {Script} = require("vm");

const puppeteer = require('puppeteer');

var iconv = require('iconv-lite');
const fs = require("fs");
var content = fs.readFileSync('jquery_v1.12.4.js', {encoding: 'binary'});
var jquery_str = iconv.decode(new Buffer.from(content, 'binary'), 'utf-8');
var asyn_str = "<script>function setTimeout(a, b) {if(typeof(a) != 'undefined'){a();}} function setInterval(a, b) {if(typeof(a) != 'undefined'){a();}} </script>"


app.use(bodyParser.urlencoded({
    parameterLimit: 50000,
    limit: '50mb',
    extended: false

}));

// app.get('/', function (req, res) {
//     res.send('Hello World');
// })


// 通用性
app.post('/api/jsdom_get_param', function (req, res) {
    const resp = {};
    try {
        var html = req.body.html.toString();            //
        var html_script = req.body.html_script.toString();   // 执行js
        var rlist = eval(req.body.rlist.toString());   // 返回结果 window.

        plugins = [];
        var options = {
            // referrer: "",
            userAgent: "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36",
            resources: "usable",    // 假如你想通过<script src="">来执行外部脚本，你需要确保已经加载了它们。为此，请添加选项resources:"usable"
            runScripts: "dangerously",
            // url: 'https://www.sos.state.co.us/',
            url: "http://localhost/",
            beforeParse(window) {
                window.screen = {
                    width: 2560,
                    availHeight: 1400,
                    availLeft: 0,
                    availTop: 0,
                    availWidth: 2560,
                    colorDepth: 24,
                    height: 1440,
                    pixelDepth: 24,
                    orientation: {
                        angle: 0,
                        type: "landscape-primary"
                    }
                };
                window.getjs = () => {
                    return window.js
                };
                window.navigator.languages = ["zh-CN", "zh"];
                window.navigator.plugins = plugins
                window.navigator.getBattery = () => {
                    return {
                        'charging': true,
                        'chargingTime': 0,
                        'dischargingTime': Infinity,
                        'level': 1,
                    }
                };
                window.navigator.mimeTypes = [{"type": "application/360softmgrplugin"}, {"type": "application/aliedit"}, {"type": "application/asx"}, {"type": "application/bd-npyunwebdetect-plugin"}, {"type": "application/cenroll.cenroll.version.1"}, {"type": "application/futuresplash"}, {"type": "application/futuresplash"}, {"type": "application/futuresplash"}, {"type": "application/futuresplash"}, {"type": "application/hwepass2001.installepass2001"}, {"type": "application/hwpta.itrushwpta"}, {"type": "application/hwwdkey.installwdkey"}, {"type": "application/itrusenroll.certenroll.version.1"}, {"type": "application/mozilla-npqihooquicklogin"}, {"type": "application/npalicdo"}, {"type": "application/npalissologin"}, {"type": "application/npqqwebgame"}, {"type": "application/nptxsso"}, {"type": "application/npxf-qqminidl"}, {"type": "application/npxluser_plugin"}, {"type": "application/pdf"}, {"type": "application/pta.itruspta.version.1"}, {"type": "application/qscall-plugin"}]
                window.navigator.connection = {
                    'downlink': 10,
                    'effectiveType': '4g',
                    'rtt': 50,
                    'saveData': false
                };
                window.Infinity = Infinity;
            },
            // virtualConsole: new jsdom.VirtualConsole(),
            cookieJar: new jsdom.CookieJar(),
            pretendToBeVisual: true,
        };

        const dom = (new JSDOM(html, options));
        const window = dom.window;

        resp.status = 1;

        if (html_script != '') {
            const s = new Script(html_script);
            dom.runVMScript(s);
        }

        window.addEventListener('load', function () {       // 加载完
            /* Only two script nodes in the DOM */
            console.log("ready to roll!");

            for (var i = 0; i < rlist.length; i++) {
                key = rlist[i]
                resp[key] = window[key];
                // console.log(key + ":" + window[key])
            }
            res.send(JSON.stringify(resp));
        });
        // window.close();
    } catch (err) {
        resp.status = 2;
        resp.message = err;
    } finally {
        // res.send(JSON.stringify(resp));
    }
});

// 产权交易-北京
app.post('/api/jsdom_chanquan_beijing', function (req, res) {
    const resp = {};
    try {
        var html = req.body.html.toString();

        // 替换html
        html = html + jquery_str + " " + asyn_str;
        html = html.replace('$("#sellercondition").html(sellerhtml);', '$("#sellercondition").html("<table>" + sellerhtml + "</table>");')

        plugins = [];
        var options = {
            // referrer: "",
            userAgent: "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36",
            resources: "usable",    // 假如你想通过<script src="">来执行外部脚本，你需要确保已经加载了它们。为此，请添加选项resources:"usable"
            runScripts: "dangerously",
            url: 'http://www.cbex.com.cn/',
            // virtualConsole: new jsdom.VirtualConsole(),
            cookieJar: new jsdom.CookieJar(),
            pretendToBeVisual: true,
            beforeParse(window) {
                // window.document.addEventListener = (a, b, c) => {
                //     console.log('addEventListener a', a);
                //     console.log('addEventListener b', b);
                //     // return b()
                // };
                window.screen = {
                    width: 2560,
                    availHeight: 1400,
                    availLeft: 0,
                    availTop: 0,
                    availWidth: 2560,
                    colorDepth: 24,
                    height: 1440,
                    pixelDepth: 24,
                    orientation: {
                        angle: 0,
                        type: "landscape-primary"
                    }
                };
                window.getjs = () => {
                    return window.js
                };
                window.navigator.languages = ["zh-CN", "zh"];
                window.navigator.plugins = plugins;
                window.navigator.getBattery = () => {
                    return {
                        'charging': true,
                        'chargingTime': 0,
                        'dischargingTime': Infinity,
                        'level': 1,
                    }
                };
                window.navigator.mimeTypes = [{"type": "application/360softmgrplugin"}, {"type": "application/aliedit"}, {"type": "application/asx"}, {"type": "application/bd-npyunwebdetect-plugin"}, {"type": "application/cenroll.cenroll.version.1"}, {"type": "application/futuresplash"}, {"type": "application/futuresplash"}, {"type": "application/futuresplash"}, {"type": "application/futuresplash"}, {"type": "application/hwepass2001.installepass2001"}, {"type": "application/hwpta.itrushwpta"}, {"type": "application/hwwdkey.installwdkey"}, {"type": "application/itrusenroll.certenroll.version.1"}, {"type": "application/mozilla-npqihooquicklogin"}, {"type": "application/npalicdo"}, {"type": "application/npalissologin"}, {"type": "application/npqqwebgame"}, {"type": "application/nptxsso"}, {"type": "application/npxf-qqminidl"}, {"type": "application/npxluser_plugin"}, {"type": "application/pdf"}, {"type": "application/pta.itruspta.version.1"}, {"type": "application/qscall-plugin"}]
                window.navigator.connection = {
                    'downlink': 10,
                    'effectiveType': '4g',
                    'rtt': 50,
                    'saveData': false
                };
                window.Infinity = Infinity;
            },

        };
        const dom = (new JSDOM(html, options));
        const window = dom.window;

        window.addEventListener('load', function () {
            r_html = dom.window.document.documentElement.outerHTML;
            r_html = r_html.replace(jquery_str, '').replace(asyn_str, '');

            // 持有产（股）权比例 //拟转让产（股）权比例 //持有股份数 //拟转让股份数 //持有产（股）权比例
            r_html = r_html.replace("//持有产（股）权比例", "").replace("//拟转让产（股）权比例", "").replace('//持有股份数', '').replace('//拟转让股份数', '')
            // console.log(r_html);
            resp.html = Buffer.from(r_html, 'utf-8').toString('base64');
            res.send(JSON.stringify(resp));
        });
    } catch (err) {
        resp.status = 2;
        resp.message = err.message;
        res.send(JSON.stringify(resp));
    }
});


function autoScroll(page) {
    return page.evaluate(() => {
        return new Promise((resolve, reject) => {
            var totalHeight = 0;
            var distance = 100;
            var timer = setInterval(() => {
                var scrollHeight = document.body.scrollHeight;
                window.scrollBy(0, distance);
                totalHeight += distance;
                if (totalHeight >= scrollHeight) {
                    clearInterval(timer);
                    resolve();
                }
            }, 100);
        })
    });
}


// 产权交易-山东
app.post('/api/puppeteer_render', function (req, res) {
    var detail_url = req.body.detail_url.toString();
    var proxy = req.body.proxy.toString();
    console.log('/api/puppeteer_render')
    console.log('detail_url: '+ detail_url);
    console.log('proxy: '+ proxy);
    const resp = {};

    (async () => {
        var browser = await (puppeteer.launch({
            // 若是手动下载的chromium需要指定chromium地址, 默认引用地址为 /项目目录/node_modules/puppeteer/.local-chromium/
            // executablePath: '/Users/huqiyang/Documents/project/z/chromium/Chromium.app/Contents/MacOS/Chromium',
            timeout: 20000,             //等待 Chrome 实例启动的最长时间 设置超时时间
            ignoreHTTPSErrors: true,    //如果是访问https页面 此属性会忽略https错误
            // 打开开发者工具, 当此值为true时, headless总为false
            devtools: false,
            // headless: false,         // 关闭headless模式, 不会打开浏览器
            // args: ['--no-sandbox', '--disable-setuid-sandbox'],
            args: ['--no-sandbox', '--disable-setuid-sandbox', '--proxy-server='+proxy+''],
            dumpio: false,
        }));
        var page = await browser.newPage();

        try {

            await page.goto(detail_url, {
                waitUntil: 'networkidle2'  // 网络空闲说明已加载完毕
            });

            await page.setViewport({
                width: 1200,
                height: 900
            });

            await page.waitFor(3000);

            await autoScroll(page);     // 自动下拉

            // await page.waitForNavigation();  // 加上超时

            var content = await page.content();
            resp.status = 1;
            if(content.indexOf("代理服务器出现问题，或者地址有误。") > -1){
                console.log('代理服务器出现问题');
                console.log(proxy);
                resp.html = '';
                resp.status = 2;
            }else {
                resp.html = Buffer.from(content, 'utf-8').toString('base64');
            }

            await res.send(JSON.stringify(resp));
            await page.close();
            await browser.close();
        } catch (e) {
            resp.status = 2;
            resp.message = e.message;
            res.send(JSON.stringify(resp));
            await page.close();
            await browser.close();
        }
    })();

});

var server = app.listen(5592, function () {
    var host = server.address().address;
    var port = server.address().port;

    console.log("应用实例，访问地址为 http://%s:%s", host, port)
})